import kotlinx.coroutines.*
import java.lang.Runnable
import kotlin.Exception

suspend fun getTime1(): Int {
    delay(1000)
    return 1
}

suspend fun getTime2(): Int {
    delay(1000)
    return 2
}


fun getTime1Async() = GlobalScope.async {
    delay(1000)
    1
}

fun getTime2Async() = GlobalScope.async {
    delay(1000)
    2
}

suspend fun countNum() = coroutineScope {
    val one = async<Int> {
        try {
            delay(5000)
            20
        } catch (e: Exception) {
            println("exception: ${e.javaClass.canonicalName}")
            println("suppressed: ${e.suppressed.joinToString { 
                it.javaClass.simpleName
            }}, size: ${e.suppressed.size}")
            20
        } finally {
            println("first task canceled")
        }
    }
    val two = async<Int> {
        delay(1000)
        throw ArithmeticException()
        10
    }
    one.await() + two.await()
}

fun main(args: Array<String>) {
    println("Hello World!")

    // Try adding program arguments via Run/Debug configuration.
    // Learn more about running applications: https://www.jetbrains.com/help/idea/running-applications.html.
    println("Program arguments: ${args.joinToString()}")

    val p = IPredicate {
        return@IPredicate false
    }
    p.accept(0);
    val runnable = Runnable {

    }

//    runBlocking {
//        val time = measureTimeMillis {
//            val job1 = getTime1()
//            val job2 = getTime2()
//            println("job result: ${job1 + job2}")
//        }
//        println("Completed in $time ms")
//    }

//    runBlocking {
//        val time = measureTimeMillis {
//            val job1 = async {
//                getTime1()
//            }
//            val job2 = async {
//                getTime2()
//            }
//            println("job result: ${job1.await() + job2.await()}")
//        }
//        println("Completed in $time ms")
//    }

    runBlocking {
        try {
            val count = countNum()
            println("count: $count")
        } catch (e: Exception) {
            println("count num exception: $e")
        }
    }


}